import { Injectable } from '@nestjs/common';
import { createReadStream, readFileSync } from 'fs';
import { readFile } from 'fs/promises';
import { Readable } from 'stream';

/**
 * 基础进制
 */
const base = Math.pow(2, 10);
/**
 * 比特
 */
const bit = 1;
/**
 * 字节
 */
const Byte = 8 * bit;
/**
 * 千字节
 */
const Kilobyte = base * Byte;
/**
 * 兆字节
 */
export const Megabyte = base * Kilobyte;
/**
 * 千兆(吉)字节
 */
const Gigabyte = base * Megabyte;
/**
 * 百万兆(太)字节
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const Terabyte = base * Gigabyte;

/**
 * @param num 字节单位
 * @param step 每次步长
 */
const genReadableBig = (num: number, step: number = 100 * Megabyte) => {
  return new Readable({
    highWaterMark: step,
    read(size) {
      console.count(`${size}`);
      if (num > step) {
        setTimeout(() => {
          this.push(Buffer.alloc(step));
          num -= step;
        }, 1e3);
      } else if (num > 0 && num < step) {
        this.push(Buffer.alloc(num));
        num = 0;
      } else {
        this.push(null);
      }
    },
  });
};

const genReadableBig2 = (num: number, step: number = 100 * Megabyte) => {
  const handler = new Readable({
    highWaterMark: step,
    read(size) {
      setTimeout(() => {
        console.count(`${size}`);
        if (num > size) {
          this.push(Buffer.alloc(size));
          num -= size;
        } else if (num > 0 && num < size) {
          this.push(Buffer.alloc(num));
          num = 0;
        } else {
          this.push(null);
        }
      }, 1e3);
    },
  });
  handler.on('readable', () => {
    while (handler.read() !== null) {
      console.log('here');
    }
  });
  return handler;
};

@Injectable()
export class DownloadService {
  downloadSimpleFile() {
    return readFile(`${__dirname}/download.service.js.map`, 'utf-8');
  }

  downloadSimpleFileWithBuffer() {
    return readFileSync(`${__dirname}/download.service.js.map`, 'utf-8');
  }

  downloadSimpleFileWithStream() {
    return createReadStream(`${__dirname}/download.service.js.map`, 'utf-8');
  }

  downloadSimpleFileWithStreamable() {
    return createReadStream(`${__dirname}/download.service.js.map`, 'utf-8');
  }

  downloadSimpleFileWithStreamableBig() {
    // return genReadableBig(0.8 * Gigabyte);
    return genReadableBig2(0.8 * Gigabyte);
  }
}
